#include "RemoteControl.h"
#include "NoCommand.h"

RemoteControl::RemoteControl(){
	//set the number of slots to a fixed value
	mNrOfSlots = 6;
	//at construction, last command is zero
	mLastcmd = 0;
	//resize the vector to 6 elements
	mSlots.resize(mNrOfSlots);
	//assign all slots to NoCommand, the device is
	//called "empty"
	ICommand * emptycmd = new NoCommand();
	for (size_t i = 1; i < mNrOfSlots; ++i){
		ProgramSlot(i, emptycmd, emptycmd, "empty");
	}
}

void RemoteControl::OnButtonPressed(size_t slotNr){
	//internally the slotnumbers reach from 0 to 5;
	slotNr--;
	//check for a valid slot number
	//if committed slot number is 0 -> underflow because of
	//size_t, this number will be out of range
	if (slotNr > mNrOfSlots - 1){
		throw std::exception("Slot number out of range");
	}
	//save the last command for undo operation
	mLastcmd = mSlots[slotNr].onCmd; 
	//execute on command from device at slot nr
	mSlots[slotNr].onCmd->Execute();
}

void RemoteControl::OffButtonPressed(size_t slotNr){
	//internally the slotnumbers reach from 0 to 5;
	slotNr--;
	//check for a valid slot number
	if (slotNr > mNrOfSlots - 1){
		throw std::exception("Slot number out of range");
	}
	//save the last command for undo operation
	mLastcmd = mSlots[slotNr].offCmd; 
	//execute off command from device at slot nr
	mSlots[slotNr].offCmd->Execute();
}

void RemoteControl::UndoButtonPressed(){
	//if a last command is available, undo it
	if (mLastcmd != 0){
		mLastcmd->Undo();
	}
}

void RemoteControl::ProgramSlot(size_t slotNr, ICommand* onCmd, ICommand* offCmd, std::string const devname){
	//internally the slotnumbers reach from 0 to 5;
	slotNr--;
	//check for invalid slot number
	if (slotNr > mNrOfSlots - 1){
		throw std::exception("Slot number out of range");
	}
	//check for invalud pointers
	else if (onCmd == 0 || offCmd == 0){
		throw std::exception("Invalid pointer of type ICommand");
	}
	//assign commands and device name to slot
	mSlots[slotNr].onCmd = onCmd;
	mSlots[slotNr].offCmd = offCmd;
	mSlots[slotNr].deviceName = devname;
}

size_t const RemoteControl::GetNrOfSlots() const{
	return mNrOfSlots;
}

std::string const RemoteControl::GetDeviceName(size_t slotNr) const{
	//internally the slotnumbers reach from 0 to 5;
	slotNr--;
	//check for a valid slot number
	if (slotNr > mNrOfSlots - 1){
		throw std::exception("Slot number out of range");
	}
	return mSlots[slotNr].deviceName;
}